﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.Windows.WebCam.PhotoCapture
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using UnityEngine.Bindings;
using UnityEngine.Scripting;
using UnityEngine.Scripting.APIUpdating;

#nullable disable
namespace UnityEngine.Windows.WebCam
{
  /// <summary>
  ///   <para>Captures a photo from the web camera and stores it in memory or on disk.</para>
  /// </summary>
  [MovedFrom("UnityEngine.XR.WSA.WebCam")]
  [NativeHeader("PlatformDependent/Win/Webcam/PhotoCapture.h")]
  [StaticAccessor("PhotoCapture", StaticAccessorType.DoubleColon)]
  [StructLayout(LayoutKind.Sequential)]
  public class PhotoCapture : IDisposable
  {
    internal IntPtr m_NativePtr;
    private static Resolution[] s_SupportedResolutions;
    private static readonly long HR_SUCCESS;

    private static PhotoCapture.PhotoCaptureResult MakeCaptureResult(
      PhotoCapture.CaptureResultType resultType,
      long hResult)
    {
      return new PhotoCapture.PhotoCaptureResult()
      {
        resultType = resultType,
        hResult = hResult
      };
    }

    private static PhotoCapture.PhotoCaptureResult MakeCaptureResult(long hResult)
    {
      return new PhotoCapture.PhotoCaptureResult()
      {
        resultType = hResult != PhotoCapture.HR_SUCCESS ? PhotoCapture.CaptureResultType.UnknownError : PhotoCapture.CaptureResultType.Success,
        hResult = hResult
      };
    }

    /// <summary>
    ///   <para>A list of all the supported device resolutions for taking pictures.</para>
    /// </summary>
    public static IEnumerable<Resolution> SupportedResolutions
    {
      get
      {
        if (PhotoCapture.s_SupportedResolutions == null)
          PhotoCapture.s_SupportedResolutions = PhotoCapture.GetSupportedResolutions_Internal();
        return (IEnumerable<Resolution>) PhotoCapture.s_SupportedResolutions;
      }
    }

    [NativeName("GetSupportedResolutions")]
    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern Resolution[] GetSupportedResolutions_Internal();

    public static void CreateAsync(
      bool showHolograms,
      PhotoCapture.OnCaptureResourceCreatedCallback onCreatedCallback)
    {
      if (onCreatedCallback == null)
        throw new ArgumentNullException(nameof (onCreatedCallback));
      PhotoCapture.Instantiate_Internal(showHolograms, onCreatedCallback);
    }

    public static void CreateAsync(
      PhotoCapture.OnCaptureResourceCreatedCallback onCreatedCallback)
    {
      if (onCreatedCallback == null)
        throw new ArgumentNullException(nameof (onCreatedCallback));
      PhotoCapture.Instantiate_Internal(false, onCreatedCallback);
    }

    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [NativeName("Instantiate")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern IntPtr Instantiate_Internal(
      bool showHolograms,
      PhotoCapture.OnCaptureResourceCreatedCallback onCreatedCallback);

    [RequiredByNativeCode]
    private static void InvokeOnCreatedResourceDelegate(
      PhotoCapture.OnCaptureResourceCreatedCallback callback,
      IntPtr nativePtr)
    {
      if (nativePtr == IntPtr.Zero)
        callback((PhotoCapture) null);
      else
        callback(new PhotoCapture(nativePtr));
    }

    private PhotoCapture(IntPtr nativeCaptureObject) => this.m_NativePtr = nativeCaptureObject;

    public void StartPhotoModeAsync(
      CameraParameters setupParams,
      PhotoCapture.OnPhotoModeStartedCallback onPhotoModeStartedCallback)
    {
      if (onPhotoModeStartedCallback == null)
        throw new ArgumentException(nameof (onPhotoModeStartedCallback));
      if (setupParams.cameraResolutionWidth == 0 || setupParams.cameraResolutionHeight == 0)
        throw new ArgumentOutOfRangeException(nameof (setupParams), "The camera resolution must be set to a supported resolution.");
      this.StartPhotoMode_Internal(setupParams, onPhotoModeStartedCallback);
    }

    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [NativeName("StartPhotoMode")]
    private void StartPhotoMode_Internal(
      CameraParameters setupParams,
      PhotoCapture.OnPhotoModeStartedCallback onPhotoModeStartedCallback)
    {
      this.StartPhotoMode_Internal_Injected(ref setupParams, onPhotoModeStartedCallback);
    }

    [RequiredByNativeCode]
    private static void InvokeOnPhotoModeStartedDelegate(
      PhotoCapture.OnPhotoModeStartedCallback callback,
      long hResult)
    {
      callback(PhotoCapture.MakeCaptureResult(hResult));
    }

    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [NativeName("StopPhotoMode")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern void StopPhotoModeAsync(
      PhotoCapture.OnPhotoModeStoppedCallback onPhotoModeStoppedCallback);

    [RequiredByNativeCode]
    private static void InvokeOnPhotoModeStoppedDelegate(
      PhotoCapture.OnPhotoModeStoppedCallback callback,
      long hResult)
    {
      callback(PhotoCapture.MakeCaptureResult(hResult));
    }

    public void TakePhotoAsync(
      string filename,
      PhotoCaptureFileOutputFormat fileOutputFormat,
      PhotoCapture.OnCapturedToDiskCallback onCapturedPhotoToDiskCallback)
    {
      if (onCapturedPhotoToDiskCallback == null)
        throw new ArgumentNullException(nameof (onCapturedPhotoToDiskCallback));
      filename = !string.IsNullOrEmpty(filename) ? filename.Replace("/", "\\") : throw new ArgumentNullException(nameof (filename));
      string directoryName = Path.GetDirectoryName(filename);
      if (!string.IsNullOrEmpty(directoryName) && !System.IO.Directory.Exists(directoryName))
        throw new ArgumentException("The specified directory does not exist.", nameof (filename));
      FileInfo fileInfo = new FileInfo(filename);
      if (fileInfo.Exists && fileInfo.IsReadOnly)
        throw new ArgumentException("Cannot write to the file because it is read-only.", nameof (filename));
      this.CapturePhotoToDisk_Internal(filename, fileOutputFormat, onCapturedPhotoToDiskCallback);
    }

    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [NativeName("CapturePhotoToDisk")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void CapturePhotoToDisk_Internal(
      string filename,
      PhotoCaptureFileOutputFormat fileOutputFormat,
      PhotoCapture.OnCapturedToDiskCallback onCapturedPhotoToDiskCallback);

    [RequiredByNativeCode]
    private static void InvokeOnCapturedPhotoToDiskDelegate(
      PhotoCapture.OnCapturedToDiskCallback callback,
      long hResult)
    {
      callback(PhotoCapture.MakeCaptureResult(hResult));
    }

    public void TakePhotoAsync(
      PhotoCapture.OnCapturedToMemoryCallback onCapturedPhotoToMemoryCallback)
    {
      if (onCapturedPhotoToMemoryCallback == null)
        throw new ArgumentNullException(nameof (onCapturedPhotoToMemoryCallback));
      this.CapturePhotoToMemory_Internal(onCapturedPhotoToMemoryCallback);
    }

    [NativeName("CapturePhotoToMemory")]
    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void CapturePhotoToMemory_Internal(
      PhotoCapture.OnCapturedToMemoryCallback onCapturedPhotoToMemoryCallback);

    [RequiredByNativeCode]
    private static void InvokeOnCapturedPhotoToMemoryDelegate(
      PhotoCapture.OnCapturedToMemoryCallback callback,
      long hResult,
      IntPtr photoCaptureFramePtr)
    {
      PhotoCaptureFrame photoCaptureFrame = (PhotoCaptureFrame) null;
      if (photoCaptureFramePtr != IntPtr.Zero)
        photoCaptureFrame = new PhotoCaptureFrame(photoCaptureFramePtr);
      callback(PhotoCapture.MakeCaptureResult(hResult), photoCaptureFrame);
    }

    /// <summary>
    ///   <para>Provides a COM pointer to the native IVideoDeviceController.</para>
    /// </summary>
    /// <returns>
    ///   <para>A native COM pointer to the IVideoDeviceController.</para>
    /// </returns>
    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [NativeName("GetUnsafePointerToVideoDeviceController")]
    [ThreadAndSerializationSafe]
    [MethodImpl(MethodImplOptions.InternalCall)]
    public extern IntPtr GetUnsafePointerToVideoDeviceController();

    /// <summary>
    ///   <para>Dispose must be called to shutdown the PhotoCapture instance.</para>
    /// </summary>
    public void Dispose()
    {
      if (this.m_NativePtr != IntPtr.Zero)
      {
        this.Dispose_Internal();
        this.m_NativePtr = IntPtr.Zero;
      }
      GC.SuppressFinalize((object) this);
    }

    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [NativeName("Dispose")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void Dispose_Internal();

    ~PhotoCapture()
    {
      if (!(this.m_NativePtr != IntPtr.Zero))
        return;
      this.DisposeThreaded_Internal();
      this.m_NativePtr = IntPtr.Zero;
    }

    [NativeConditional("(PLATFORM_WIN || PLATFORM_WINRT) && !PLATFORM_XBOXONE")]
    [ThreadAndSerializationSafe]
    [NativeName("DisposeThreaded")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void DisposeThreaded_Internal();

    [MethodImpl(MethodImplOptions.InternalCall)]
    private extern void StartPhotoMode_Internal_Injected(
      ref CameraParameters setupParams,
      PhotoCapture.OnPhotoModeStartedCallback onPhotoModeStartedCallback);

    /// <summary>
    ///   <para>Contains the result of the capture request.</para>
    /// </summary>
    public enum CaptureResultType
    {
      /// <summary>
      ///   <para>Specifies that the desired operation was successful.</para>
      /// </summary>
      Success,
      /// <summary>
      ///   <para>Specifies that an unknown error occurred.</para>
      /// </summary>
      UnknownError,
    }

    /// <summary>
    ///   <para>A data container that contains the result information of a photo capture operation.</para>
    /// </summary>
    public struct PhotoCaptureResult
    {
      /// <summary>
      ///   <para>A generic result that indicates whether or not the PhotoCapture operation succeeded.</para>
      /// </summary>
      public PhotoCapture.CaptureResultType resultType;
      /// <summary>
      ///   <para>The specific HResult value.</para>
      /// </summary>
      public long hResult;

      /// <summary>
      ///   <para>Indicates whether or not the operation was successful.</para>
      /// </summary>
      public bool success => this.resultType == PhotoCapture.CaptureResultType.Success;
    }

    /// <summary>
    ///   <para>Called when a PhotoCapture resource has been created.</para>
    /// </summary>
    /// <param name="captureObject">The PhotoCapture instance.</param>
    public delegate void OnCaptureResourceCreatedCallback(PhotoCapture captureObject);

    /// <summary>
    ///   <para>Called when photo mode has been started.</para>
    /// </summary>
    /// <param name="result">Indicates whether or not photo mode was successfully activated.</param>
    public delegate void OnPhotoModeStartedCallback(PhotoCapture.PhotoCaptureResult result);

    /// <summary>
    ///   <para>Called when photo mode has been stopped.</para>
    /// </summary>
    /// <param name="result">Indicates whether or not photo mode was successfully deactivated.</param>
    public delegate void OnPhotoModeStoppedCallback(PhotoCapture.PhotoCaptureResult result);

    /// <summary>
    ///   <para>Called when a photo has been saved to the file system.</para>
    /// </summary>
    /// <param name="result">Indicates whether or not the photo was successfully saved to the file system.</param>
    public delegate void OnCapturedToDiskCallback(PhotoCapture.PhotoCaptureResult result);

    /// <summary>
    ///   <para>Called when a photo has been captured to memory.</para>
    /// </summary>
    /// <param name="result">Indicates whether or not the photo was successfully captured to memory.</param>
    /// <param name="photoCaptureFrame">Contains the target texture.  If available, the spatial information will be accessible through this structure as well.</param>
    public delegate void OnCapturedToMemoryCallback(
      PhotoCapture.PhotoCaptureResult result,
      PhotoCaptureFrame photoCaptureFrame);
  }
}
